#!/usr/bin/env python
# -*- coding: utf-8 -*-


import time
from datetime import datetime, timedelta

from commons.logger import log
from commons.assert_tools import Assert


class TimeFormat:
    """时间格式化"""
    @staticmethod
    def now_time(fmt: str = "%Y-%m-%d") -> str:
        """
        当前时间
        :param fmt: 时间格式
        :return: 返回当前时间
        """
        try:
            return datetime.now().strftime(fmt)
        except Exception as e:
            log.error(e)

    def now_month_range(fmt: str = "%Y-%m-%d") -> tuple[str, str]:
        """
        获取当月首尾日期，并按照指定格式返回字符串形式的日期。

        参数:
        fmt (str): 日期格式化字符串，默认为 "%Y-%m-%d"。

        返回:
        tuple[str, str]: 包含当月开始日期和当月结束日期的字符串元组，格式由 fmt 参数指定。
        """
        # 获取当前日期
        today = datetime.today()

        # 获取当月开始日期
        start_date = today.replace(day=1)

        try:
            # 获取下个月开始日期，需要考虑跨年的情况
            if start_date.month == 12:
                next_month = start_date.replace(year=start_date.year + 1, month=1, day=1)
            else:
                next_month = start_date.replace(month=start_date.month + 1, day=1)
        except ValueError:
            # 如果出现值错误（比如2月29日在非闰年时设置月份等情况），进行特殊处理
            # 这里简单示例为将日期设置为当月最后一天（可根据实际需求完善更精准的处理逻辑）
            import calendar
            last_day_of_month = calendar.monthrange(start_date.year, start_date.month)[1]
            start_date = start_date.replace(day=last_day_of_month)
            return start_date.strftime(fmt), start_date.strftime(fmt)

        # 获取当月结束日期
        end_date = next_month - timedelta(days=1)

        return start_date.strftime(fmt), end_date.strftime(fmt)

    @staticmethod
    def before_n_days(n: int = -1, fmt: str = "%Y-%m-%d"):
        now = datetime.now()
        mouths_before = now + timedelta(days=n)
        return mouths_before.strftime(fmt)

    @staticmethod
    def n_days_later(n, fmt):
        """
        n天后的时间
        :param n: 天数
        :param fmt: 时间格式
        :return: 返回n天后的时间
        """
        try:
            fmt_time = (datetime.now() +
                        timedelta(days=n)).strftime(fmt)
            return fmt_time
        except Exception as e:
            log.error(e)

    @staticmethod
    def get_time_nday_later(n:int):
        """
        获取n天后当前时间点的时间，并格式化为指定字符串格式返回

        Returns:
            str: 格式为 '%Y-%m-%d %H:%M:%S' 的1天后当前时间点的时间字符串
        """
        # 获取当前时间
        current_time = datetime.now()
        # 定义时间间隔为1天
        one_day_delta = timedelta(days=n)
        # 计算1天后的时间
        future_time = current_time + one_day_delta
        # 将时间格式化为指定格式
        formatted_time = future_time.strftime('%Y-%m-%d %H:%M:%S')
        return formatted_time

    @staticmethod
    def n_hours_later(n, fmt):
        """
        n小时后的时间
        :param n: 小时数
        :param fmt: 时间戳格式
        :return:
        """
        try:
            fmt_time = (datetime.now() +
                        timedelta(hours=n)).strftime(fmt)
            return fmt_time
        except Exception as e:
            log.error(e)

    @staticmethod
    def n_minutes_later(n, fmt):
        """
        n分钟后的时间
        :param n: 分钟
        :param fmt: 时间戳格式
        :return:
        """
        try:
            fmt_time = (datetime.now() +
                        timedelta(minutes=n)).strftime(fmt)
            return fmt_time
        except Exception as e:
            log.error(e)

    @staticmethod
    def n_seconds_later(n, fmt):
        """
        n秒后的时间
        :param n: 秒钟
        :param fmt: 时间戳格式
        :return:
        """
        try:
            fmt_time = (datetime.now() +
                        timedelta(seconds=n)).strftime(fmt)
            return fmt_time
        except Exception as e:
            log.error(e)

    @staticmethod
    def get_now_timestamp() -> int:
        """获取当前时间，并返回时间戳(13位毫秒级)
        :return: 当前时间戳
        :rtype: int
        """
        timestamp = int(datetime.now().timestamp() * 1000)
        return timestamp

    @staticmethod
    def minutes_later_timestamp(n):
        """
        n分钟后的时间戳
        :param n: 分钟
        :return:
        """
        try:
            timestamp = (datetime.now() +
                         timedelta(minutes=n))
            return timestamp
        except Exception as e:
            log.error(e)

    @staticmethod
    def timestamp_to_fmt_time(timestamp, fmt="%Y-%m-%d %H:%M:%S") -> str:
        """
        13位时间戳转化成时间格式
        :param timestamp: 时间戳
        :return:
        """
        timeStamp = float(timestamp / 1000)
        timeArray = time.localtime(timeStamp)
        otherStyleTime = time.strftime(fmt, timeArray)
        return otherStyleTime

    @staticmethod
    def tm_stamp(num=10):
        """
        获取指定位数的当前时间戳
        num 需获取的时间戳的位数
        """
        if num == 10:
            time_stamp = int(time.time())  # 时间戳10位
            log.info("获取到%s位数的时间戳为%s:" % (str(time_stamp), str(num)))
            return time_stamp
        elif num == 13:
            time_stamp = round(time.time() * 1000)  # 时间戳13位
            log.info("获取到%s位数的时间戳为%s:" % (str(time_stamp), str(num)))
            return time_stamp
        else:
            Assert().fail_assert("您要获取时间戳位数为:%s,未定义该位数的时间转换,请检查参数,或在函数里增加该逻辑!")



    @staticmethod
    def to_stamp(str_time, time_format='%Y-%m-%d %H:%M:%S'):
        """
        指定时间转换成时间戳
        str_time 指定的具体时间字符串               如2024-06-22 18:14:12
        time_format 时间格式,与str_time格式保持一致 如"%Y-%m-%d %H:%M:%S"
        """
        date_array = time.strptime(str_time, time_format)
        time_stamp = int(time.mktime(date_array))
        log.info("指定时间:%s,转换为时间戳的值为:%s" % (str_time, str(time_stamp)))
        return time_stamp

    @staticmethod
    def record():
        """用于记录操作时间/执行用例的时间(记录时间专用)"""
        time_str =  int(time.time())
        time_record = log.info("* * * * * * 执行/操作时间为:%s" % str(time_str) + " * * * * * *")
        return time_record

    @staticmethod
    def get_future_time(n):
        """
        生成指定的n分钟以后的时间，格式化为HH:MM的形式

        参数:
        n (int): 表示要往后推的分钟数

        返回值:
        str: 格式化后的时间字符串，格式为HH:MM
        """
        now = datetime.now()
        future_time = now + timedelta(minutes=n)
        return future_time.strftime('%H:%M')


time_fmt = TimeFormat()

if __name__ == '__main__':
    # print(TimeFormat.now_time())
    # print(time_fmt.now_month_range())
    # print(time_fmt.record())
    print(TimeFormat.get_time_nday_later(3))
    print(TimeFormat.get_future_time(2))

